package com.insight.modules.system.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import com.insight.common.api.vo.Result;
import com.insight.common.constant.CommonConstant;
import com.insight.common.system.base.controller.JeecgController;
import com.insight.common.system.query.QueryGenerator;
import com.insight.common.util.oConvertUtils;
import com.insight.modules.system.entity.SysDepartPermission;
import com.insight.modules.system.entity.SysDepartRolePermission;
import com.insight.modules.system.entity.SysPermission;
import com.insight.modules.system.entity.SysPermissionDataRule;
import com.insight.modules.system.model.TreeModel;
import com.insight.modules.system.service.ISysDepartPermissionService;
import com.insight.modules.system.service.ISysDepartRolePermissionService;
import com.insight.modules.system.service.ISysPermissionDataRuleService;
import com.insight.modules.system.service.ISysPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

 /**
 * @Description: 部门权限表
 * @Author: jeecg-boot
 * @Date:   2020-02-11
 * @Version: V1.0
 */
@Slf4j
@Api(tags="部门权限表")
@RestController
@RequestMapping("/sys/sysDepartPermission")
@Slf4j
@Api(tags="部门权限表")
@RestController
@RequestMapping("/sys/sysDepartPermission")
public class SysDepartPermissionController extends JeecgController<SysDepartPermission, ISysDepartPermissionService> {

	 // 部门权限服务接口，用于操作部门权限表相关业务
	 @Autowired
	 private ISysDepartPermissionService sysDepartPermissionService;

	 // 权限数据规则服务接口，用于获取权限对应的数据规则
	 @Autowired
	 private ISysPermissionDataRuleService sysPermissionDataRuleService;

	 // 权限服务接口，用于查询权限信息
	 @Autowired
	 private ISysPermissionService sysPermissionService;

	 // 部门角色权限关联服务，用于部门角色与权限关系管理
	 @Autowired
	 private ISysDepartRolePermissionService sysDepartRolePermissionService;

	 /**
	  * 分页查询部门权限列表
	  *
	  * @param sysDepartPermission 部门权限实体，封装查询条件
	  * @param pageNo             当前页码，默认1
	  * @param pageSize           每页记录数，默认10
	  * @param req                HTTP请求，获取请求参数
	  * @return 分页查询结果，包含部门权限列表和分页信息
	  */
	 @ApiOperation(value="部门权限表-分页列表查询", notes="部门权限表-分页列表查询")
	 @GetMapping(value = "/list")
	 public Result<?> queryPageList(SysDepartPermission sysDepartPermission,
									@RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
									@RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
									HttpServletRequest req) {
		 // 使用工具类生成查询包装器，支持多条件查询
		 QueryWrapper<SysDepartPermission> queryWrapper = QueryGenerator.initQueryWrapper(sysDepartPermission, req.getParameterMap());
		 // 构造分页对象
		 Page<SysDepartPermission> page = new Page<>(pageNo, pageSize);
		 // 执行分页查询
		 IPage<SysDepartPermission> pageList = sysDepartPermissionService.page(page, queryWrapper);
		 // 返回查询结果
		 return Result.ok(pageList);
	 }

	 /**
	  * 新增部门权限记录
	  *
	  * @param sysDepartPermission 部门权限实体，JSON请求体传入
	  * @return 操作结果
	  */
	 @ApiOperation(value="部门权限表-添加", notes="部门权限表-添加")
	 @PostMapping(value = "/add")
	 public Result<?> add(@RequestBody SysDepartPermission sysDepartPermission) {
		 // 调用服务保存部门权限
		 sysDepartPermissionService.save(sysDepartPermission);
		 return Result.ok("添加成功！");
	 }

	 /**
	  * 编辑部门权限记录
	  *
	  * @param sysDepartPermission 部门权限实体，包含修改后的字段
	  * @return 操作结果
	  */
	 @ApiOperation(value="部门权限表-编辑", notes="部门权限表-编辑")
	 @PutMapping(value = "/edit")
	 public Result<?> edit(@RequestBody SysDepartPermission sysDepartPermission) {
		 // 根据ID更新部门权限信息
		 sysDepartPermissionService.updateById(sysDepartPermission);
		 return Result.ok("编辑成功!");
	 }

	 /**
	  * 通过ID删除单条部门权限数据
	  *
	  * @param id 部门权限ID
	  * @return 操作结果
	  */
	 @ApiOperation(value="部门权限表-通过id删除", notes="部门权限表-通过id删除")
	 @DeleteMapping(value = "/delete")
	 public Result<?> delete(@RequestParam(name="id",required=true) String id) {
		 // 调用服务删除指定ID的部门权限
		 sysDepartPermissionService.removeById(id);
		 return Result.ok("删除成功!");
	 }

	 /**
	  * 批量删除部门权限数据
	  *
	  * @param ids 多个部门权限ID，逗号分隔
	  * @return 操作结果
	  */
	 @ApiOperation(value="部门权限表-批量删除", notes="部门权限表-批量删除")
	 @DeleteMapping(value = "/deleteBatch")
	 public Result<?> deleteBatch(@RequestParam(name="ids",required=true) String ids) {
		 // 将字符串分割为列表，并调用服务批量删除
		 this.sysDepartPermissionService.removeByIds(Arrays.asList(ids.split(",")));
		 return Result.ok("批量删除成功！");
	 }

	 /**
	  * 根据ID查询部门权限详情
	  *
	  * @param id 部门权限ID
	  * @return 查询到的部门权限实体
	  */
	 @ApiOperation(value="部门权限表-通过id查询", notes="部门权限表-通过id查询")
	 @GetMapping(value = "/queryById")
	 public Result<?> queryById(@RequestParam(name="id",required=true) String id) {
		 // 根据ID查询部门权限
		 SysDepartPermission sysDepartPermission = sysDepartPermissionService.getById(id);
		 return Result.ok(sysDepartPermission);
	 }

	 /**
	  * 导出部门权限数据到Excel
	  *
	  * @param request HTTP请求对象
	  * @param sysDepartPermission 查询条件
	  * @return Excel视图
	  */
	 @RequestMapping(value = "/exportXls")
	 public ModelAndView exportXls(HttpServletRequest request, SysDepartPermission sysDepartPermission) {
		 // 调用父类导出Excel方法
		 return super.exportXls(request, sysDepartPermission, SysDepartPermission.class, "部门权限表");
	 }

	 /**
	  * 通过Excel导入部门权限数据
	  *
	  * @param request  HTTP请求对象
	  * @param response HTTP响应对象
	  * @return 导入结果
	  */
	 @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
	 public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
		 // 调用父类导入Excel方法
		 return super.importExcel(request, response, SysDepartPermission.class);
	 }

	 /**
	  * 获取指定权限ID对应的权限数据规则及部门权限配置
	  *
	  * @param permissionId 权限ID
	  * @param departId 部门ID
	  * @return 包含权限数据规则列表及已选规则ID的结果集
	  */
	 @GetMapping(value = "/datarule/{permissionId}/{departId}")
	 public Result<?> loadDatarule(@PathVariable("permissionId") String permissionId,
								   @PathVariable("departId") String departId) {
		 // 获取该权限的所有数据规则
		 List<SysPermissionDataRule> list = sysPermissionDataRuleService.getPermRuleListByPermId(permissionId);
		 if(list == null || list.isEmpty()) {
			 // 如果权限数据规则为空，返回错误
			 return Result.error("未找到权限配置信息");
		 } else {
			 // 结果Map，包含数据规则及部门权限的已选规则IDs
			 Map<String,Object> map = new HashMap<>();
			 map.put("datarule", list);
			 // 查询部门权限中该权限对应的记录
			 LambdaQueryWrapper<SysDepartPermission> query = new LambdaQueryWrapper<SysDepartPermission>()
					 .eq(SysDepartPermission::getPermissionId, permissionId)
					 .eq(SysDepartPermission::getDepartId, departId);
			 SysDepartPermission sysDepartPermission = sysDepartPermissionService.getOne(query);
			 if(sysDepartPermission != null) {
				 String drChecked = sysDepartPermission.getDataRuleIds();
				 if(oConvertUtils.isNotEmpty(drChecked)) {
					 // 去除可能的末尾逗号，防止前端处理异常
					 map.put("drChecked", drChecked.endsWith(",") ? drChecked.substring(0, drChecked.length()-1) : drChecked);
				 }
			 }
			 return Result.ok(map);
			 // 备注：将来按钮权限查询也可集成到此接口，只需扩展map结构
		 }
	 }

	 /**
	  * 保存部门权限对应的数据规则ID集合
	  *
	  * @param jsonObject JSON请求体，必须包含permissionId、departId、dataRuleIds
	  * @return 操作结果
	  */
	 @PostMapping(value = "/datarule")
	 public Result<?> saveDatarule(@RequestBody JSONObject jsonObject) {
		 try {
			 if (jsonObject == null) {
				 return Result.error("请求参数为空");
			 }
			 String permissionId = jsonObject.getString("permissionId");
			 String departId = jsonObject.getString("departId");
			 String dataRuleIds = jsonObject.getString("dataRuleIds");
			 log.info("保存数据规则>> 菜单ID:{} 部门ID:{} 数据权限ID:{}", permissionId, departId, dataRuleIds);
			 if (permissionId == null || departId == null) {
				 return Result.error("菜单ID或部门ID为空");
			 }
			 LambdaQueryWrapper<SysDepartPermission> query = new LambdaQueryWrapper<SysDepartPermission>()
					 .eq(SysDepartPermission::getPermissionId, permissionId)
					 .eq(SysDepartPermission::getDepartId, departId);
			 SysDepartPermission sysDepartPermission = sysDepartPermissionService != null ? sysDepartPermissionService.getOne(query) : null;
			 if (sysDepartPermission == null) {
				 return Result.error("请先保存部门菜单权限!");
			 } else {
				 sysDepartPermission.setDataRuleIds(dataRuleIds);
				 if (this.sysDepartPermissionService != null) {
					 this.sysDepartPermissionService.updateById(sysDepartPermission);
				 }
			 }
		 } catch (Exception e) {
			 log.error("SysDepartPermissionController.saveDatarule()发生异常：", e);
			 return Result.error("保存失败");
		 }
		 return Result.ok("保存成功!");
	 }

	 /**
	  * 查询指定角色ID的部门权限授权列表
	  *
	  * @param roleId 角色ID
	  * @return 已授权的权限ID列表
	  */
	 @RequestMapping(value = "/queryDeptRolePermission", method = RequestMethod.GET)
	 public Result<List<String>> queryDeptRolePermission(
			 @RequestParam(name = "roleId", required = true) String roleId) {

		 Result<List<String>> result = new Result<>();

		 // 1. 先做参数校验（防御空字符串）
		 if (roleId == null || roleId.trim().isEmpty()) {
			 result.error500("roleId 不能为空");
			 return result;
		 }

		 // 2. 查询数据（MyBatis-Plus 的 list() 不会返回 null，所以 list 本身安全）
		 List<SysDepartRolePermission> list = sysDepartRolePermissionService.list(
				 new QueryWrapper<SysDepartRolePermission>()
						 .lambda()
						 .eq(SysDepartRolePermission::getRoleId, roleId));

		 // 3. 安全地提取 permissionId：过滤 null 值，避免 String.valueOf(null) 产生 "null"
		 List<String> permissionIds = list.stream()
				 .map(SysDepartRolePermission::getPermissionId)
				 .filter(Objects::nonNull)
				 .map(String::valueOf)
				 .collect(Collectors.toList());

		 // 4. 设置成功结果
		 result.setResult(permissionIds);
		 result.setSuccess(true);

		 return result;
	 }

	 /**
	  * 保存角色的部门权限授权信息
	  *
	  * @param json 请求参数，包含roleId（角色ID）、permissionIds（新权限ID列表）、lastpermissionIds（旧权限ID列表）
	  * @return 授权操作结果
	  */
	 @RequestMapping(value = "/saveDeptRolePermission", method = RequestMethod.POST)
	 public Result<String> saveDeptRolePermission(@RequestBody JSONObject json) {
		 long start = System.currentTimeMillis();
		 Result<String> result = new Result<>();
		 try {
			 if (json == null) {
				 return result.error500("请求参数为空");
			 }
			 String roleId = json.getString("roleId");
			 String permissionIds = json.getString("permissionIds");
			 String lastPermissionIds = json.getString("lastpermissionIds");
			 if (this.sysDepartRolePermissionService != null) {
				 this.sysDepartRolePermissionService.saveDeptRolePermission(roleId, permissionIds, lastPermissionIds);
			 }
			 result.success("保存成功！");
			 log.info("======部门角色授权成功=====耗时:{} 毫秒", System.currentTimeMillis() - start);
		 } catch (Exception e) {
			 result.error500("授权失败！");
			 log.error(e.getMessage(), e);
		 }
		 return result;
	 }

	 /**
	  * 查询部门角色对应的菜单权限树，用于授权页面展示
	  *
	  * @param departId 部门ID，必须传入
	  * @param request  HTTP请求对象
	  * @return 包含权限树数据和已授权权限ID列表的Map结构
	  */
	 @RequestMapping(value = "/queryTreeListForDeptRole", method = RequestMethod.GET)
	 public Result<Map<String,Object>> queryTreeListForDeptRole(@RequestParam(name="departId",required=true) String departId,
																HttpServletRequest request) {
		 Result<Map<String,Object>> result = new Result<>();
		 List<String> ids = new ArrayList<>();
		 try {
			 if (departId == null || sysPermissionService == null) {
				 result.setSuccess(false);
				 return result;
			 }
			 LambdaQueryWrapper<SysPermission> query = new LambdaQueryWrapper<>();
			 query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0);
			 query.orderByAsc(SysPermission::getSortNo);
			 query.inSql(SysPermission::getId, "select permission_id from sys_depart_permission where depart_id='" + departId + "'");
			 List<SysPermission> list = sysPermissionService.list(query);

			 if (list != null) {
				 for (SysPermission sysPer : list) {
					 if (sysPer != null && sysPer.getId() != null) {
						 ids.add(sysPer.getId());
					 }
				 }
			 }

			 List<TreeModel> treeList = new ArrayList<>();
			 getTreeModelList(treeList, list, null);

			 Map<String,Object> resMap = new HashMap<>();
			 resMap.put("treeList", treeList);
			 resMap.put("ids", ids);
			 result.setResult(resMap);
			 result.setSuccess(true);
		 } catch (Exception e) {
			 log.error(e.getMessage(), e);
		 }
		 return result;
	 }

	 /**
	  * 递归生成权限树形结构
	  *
	  * @param treeList 结果树列表，传入空列表
	  * @param metaList 权限原始列表
	  * @param temp     当前节点，首次调用时为null表示根节点
	  */
	 private void getTreeModelList(List<TreeModel> treeList, List<SysPermission> metaList, TreeModel temp) {
		 for (SysPermission permission : metaList) {
			 String tempPid = permission.getParentId();
			 // 创建树节点，包含权限ID、父ID、名称、规则标记及是否叶子节点
			 TreeModel tree = new TreeModel(permission.getId(), tempPid, permission.getName(),
					 permission.getRuleFlag(), permission.isLeaf());
			 if (temp == null && oConvertUtils.isEmpty(tempPid)) {
				 // 当前处理为根节点
				 treeList.add(tree);
				 // 非叶子节点递归调用
				 if (!tree.getIsLeaf()) {
					 getTreeModelList(treeList, metaList, tree);
				 }
			 } else if (temp != null && tempPid != null && tempPid.equals(temp.getKey())) {
				 // 当前节点为父节点的子节点，添加到父节点children集合
				 temp.getChildren().add(tree);
				 if (!tree.getIsLeaf()) {
					 getTreeModelList(treeList, metaList, tree);
				 }
			 }
		 }
	 }
 }

